//#define _WINSOCK_DEPRECATED_NO_WARNINGS
//#define _CRT_SECURE_NO_WARNINGS
//
//#include <stdio.h>
//#include <stdlib.h>
//
//#include <winsock2.h>
//#pragma comment(lib,"ws2_32.lib")
//
///*--------------------------------------------------------------------------*/
//#define MAX_MSG_SIZE 1024
//

//BYTE  bSendBuf[1500];
//BYTE  bRcvBuf[1500];
//struct sockaddr_in gSvrSocketAddr031428;
//fd_set gsReadFdSet031428;
//
///*--------------------------------------------------------------------------*/
//void printMsg_WSAGetLastError(){
//    LPVOID lpMsgBuf;
//    int nErrorCode;
//
//    nErrorCode = WSAGetLastError();
//    FormatMessage(
//        FORMAT_MESSAGE_ALLOCATE_BUFFER |
//        FORMAT_MESSAGE_FROM_SYSTEM |
//        FORMAT_MESSAGE_IGNORE_INSERTS,
//        NULL,
//        nErrorCode,
//        0, //Language Identifiers 0x0804, // zh-ch:0x0804,en-us:0x0409,
//        (LPTSTR) &lpMsgBuf,
//        0,
//        NULL
//    );
//    printf("WSAGetLastError()=%d, %s\n", nErrorCode, lpMsgBuf);
//    LocalFree( lpMsgBuf );
//}
///*--------------------------------------------------------------------------*/
//int getLocalSocketAddrName(int socketFd){
//    struct sockaddr_in SocketAddr;
//    int nLen;
//    int nRet;
//      
//    memset(&SocketAddr, 0, sizeof(struct sockaddr_in) );
//    nLen = sizeof(struct sockaddr_in);
//    nRet = getsockname ( socketFd, (SOCKADDR *)&SocketAddr, &nLen );
//    if( 0 == nRet ){
//        printf("socketfd=%d local[ip=%d.%d.%d.%d,port=%d]\n", 
//            socketFd,
//            *( (BYTE *)&SocketAddr.sin_addr     ),
//            *( (BYTE *)&SocketAddr.sin_addr + 1 ),
//            *( (BYTE *)&SocketAddr.sin_addr + 2 ),
//            *( (BYTE *)&SocketAddr.sin_addr + 3 ),
//            ntohs(SocketAddr.sin_port)  );
//        return 0;
//    }
//    else{
//        printf("socketfd=%d,getsockname failure: ",socketFd);
//        printMsg_WSAGetLastError();
//        return -1;
//    }
//}
///*--------------------------------------------------------------------------*/
//int getPeerSocketAddrName(int socketFd){
//    struct sockaddr_in SocketAddr;
//    int nLen;
//    int nRet;
//      
//    memset(&SocketAddr, 0, sizeof(struct sockaddr_in) );
//    nLen = sizeof(struct sockaddr_in);
//    nRet = getpeername ( socketFd, (SOCKADDR *)&SocketAddr, &nLen );
//    if( 0 == nRet ){
//        printf("socketfd=%d peer[ip=%d.%d.%d.%d,port=%d]\n", 
//            socketFd,
//            *( (BYTE *)&SocketAddr.sin_addr     ),
//            *( (BYTE *)&SocketAddr.sin_addr + 1 ),
//            *( (BYTE *)&SocketAddr.sin_addr + 2 ),
//            *( (BYTE *)&SocketAddr.sin_addr + 3 ),
//            ntohs(SocketAddr.sin_port)  );
//        return 0;
//    }
//    else{
//        printf("socketfd=%d,getpeername failure: ",socketFd);
//        printMsg_WSAGetLastError();
//        return -1;
//    }   
//}
///*--------------------------------------------------------------------------*/
//int WINAPI threadIoSelect031428(LPVOID lpParam){
//    fd_set readFdSet031428;
//    int listenSocketFd031428;
//    int dataSocketFd031428;
//    int nBytesRead;
//    int nRetcode;
//    int fd031428;
//    int i;
//    
//    listenSocketFd031428 = (int)lpParam;
//    while(1){
//        FD_ZERO(&readFdSet031428);
//
//        readFdSet031428 = gsReadFdSet031428;
//
//        printf("select input fdset031428 : ");
//        for(i = 0; i < (int)readFdSet031428.fd_count; i++){
//            fd031428 = readFdSet031428.fd_array[i];
//            printf("%d ", fd031428);
//        }   
//        printf("\n");
//        
//        nRetcode = select(0, &readFdSet031428, NULL, NULL, NULL);
//        if( 0 == nRetcode)
//            continue;
//        if( 0 > nRetcode){
//            printf("select failure: ");
//            printMsg_WSAGetLastError();
//            break;
//        }
//        
//        printf("select output fdset031428 : ");
//        for(i = 0; i < (int)readFdSet031428.fd_count; i++){
//            fd031428 = readFdSet031428.fd_array[i];
//            printf("%d ", fd031428);
//        }   
//        printf("\n");
//
//        for(i = 0; i < (int)readFdSet031428.fd_count; i++){
//            fd031428 = readFdSet031428.fd_array[i];
//            if(fd031428 == listenSocketFd031428){
//                //listen socket fd
//                dataSocketFd031428 = accept(listenSocketFd031428, NULL, NULL);//non-block
//                if( dataSocketFd031428 <= 0 ){
//                    printf("socketfd031428=%d,accept failure: ", listenSocketFd031428);
//                    printMsg_WSAGetLastError();
//                    
//                    FD_CLR(listenSocketFd031428, &gsReadFdSet031428);
//                    continue;
//                }
//                else{
//                    printf("listenSocketFd031428=%d accept success, new client coming socketfd031428=%d\n", listenSocketFd031428, dataSocketFd031428);
//                    getLocalSocketAddrName(dataSocketFd031428);
//                    getPeerSocketAddrName(dataSocketFd031428);
//                    FD_SET(dataSocketFd031428, &gsReadFdSet031428);
//                }                              
//            }
//            else{
//                //data socket fd
//                memset(bRcvBuf,0,1500);
//                nBytesRead = recv( fd031428, bRcvBuf, MAX_MSG_SIZE, 0);
//                if( 0 >= nBytesRead ){
//                    printf("socketfd031428=%d:data socket error,close\n",fd031428);
//                    printMsg_WSAGetLastError();
//
//                    FD_CLR(fd031428, &gsReadFdSet031428);
//                    closesocket(fd031428);
//
//                    continue;
//                }
//                else{
//                    getLocalSocketAddrName(fd031428);
//                    getPeerSocketAddrName(fd031428);
//                    printf("socketfd031428=%d, recv msglen=%d, msg=", fd031428, nBytesRead );
//                    printf("%s\n", bRcvBuf);
//                }                
//            }
//        }
//    }
//    
//    return 0;
//}
///*--------------------------------------------------------------------------*/
//
//int main(){
//    WORD wVersionRequested;
//    WSADATA wsaData;
//    int nRetCode;
//    int socketfd031428 = -1;
//    int nSendDataFd031428;
//    int nBytesTx;
//    char c;
//
//    wVersionRequested = 0x0202;
//    nRetCode = WSAStartup(wVersionRequested, &wsaData);
//    if (nRetCode != 0){
//        printf("WSAStartup failed with error: %d\n", nRetCode);
//        return -1;
//    }
//    else
//        printf("WSAStartup sucess to startup\n");
//    if(wsaData.wVersion != wVersionRequested){
//        printf("requied wVersion=0x%04x,returned wVersion=0x%04x,returned HighestVersion=0x%04x\n",
//                wVersionRequested,
//                wsaData.wVersion,
//                wsaData.wHighVersion );
//        WSACleanup();
//        return -1;
//    }
//
//    socketfd031428 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//    if(socketfd031428 < 0){
//        printf("socket create failure,reason:\n");
//        printMsg_WSAGetLastError();
//
//        WSACleanup();
//        return -1;
//    }
//    else
//        printf("socket create success,socketfd031428=%d\n",socketfd031428);
//
//    memset(&gSvrSocketAddr031428, 0, sizeof(struct sockaddr_in) );
//    gSvrSocketAddr031428.sin_family = AF_INET;
//    gSvrSocketAddr031428.sin_port = htons(6666);
//    gSvrSocketAddr031428.sin_addr.s_addr = inet_addr("127.0.0.1");
//    nRetCode = bind( socketfd031428, (SOCKADDR *)&gSvrSocketAddr031428, sizeof(SOCKADDR) );
//    if( 0 != nRetCode){
//        printf("socket bind failure,reason:\n");
//        printMsg_WSAGetLastError();
//
//        closesocket(socketfd031428);
//        WSACleanup();
//        return -1;
//    }
//    else
//        printf("socket bind success\n");
//
//    nRetCode = listen(socketfd031428, SOMAXCONN);
//    if( 0 != nRetCode ){
//        printf("socket listen failure,reason:\n");
//        printMsg_WSAGetLastError();
//
//        closesocket(socketfd031428);
//        WSACleanup();
//        return -1;
//    }
//    
//    //memset(&gsReadFdSet, 0, sizeof(fd_set));
//    FD_ZERO(&gsReadFdSet031428);
//    
//    FD_SET(socketfd031428, &gsReadFdSet031428);
//
//    CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
//                         0,
//                         (LPTHREAD_START_ROUTINE) threadIoSelect031428,
//                         (LPVOID)socketfd031428,
//                         0, NULL );
//    printf("create thread: threadIoSelect031428\n");
//
//    //c = getchar();
//    while(1){
//        fflush(stdin);
//        c = getchar();
//        
//        printf("please input client(socketfd) you want to send:\n");
//        scanf("%d",&nSendDataFd031428);
//        
//        printf("please input msg you want to send:\n");
//        memset(bSendBuf, 0, 1500);
//        scanf("%s",bSendBuf);
//
//        nBytesTx = send(nSendDataFd031428, bSendBuf, strlen(bSendBuf), 0);
//        if(0 >= nBytesTx){
//            printf("socketfd031428=%d send failure,reason:\n", nSendDataFd031428);
//            printMsg_WSAGetLastError();
//        }
//        else
//            printf("socketfd031428=%d: send msglen=%d\n", nSendDataFd031428, nBytesTx);
//    }
//
//    WSACleanup();
//    
//    return 0;
//}
//
//
